package com.world.rickcloudendpoint.service.net.tcp.client;

import com.world.rickcloudendpoint.common.constant.GlobalConstants;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @description: 传送 信号 client
 * @author: jlsong
 * @date: 2021/12/07 00:09:57
 * @version: 1.0
 */
@Component
@Log4j2
public class TransmissionClient {

    @Value("${netty.tcp.transmission.port}")
    private Integer port;

    @Value("${netty.tcp.transmission.host}")
    private String host;

    private EventLoopGroup group = new NioEventLoopGroup();

    private SocketChannel socketChannel;

    /**
     * 发送消息
     */
    public void sendMsg(String msg) {
        if (socketChannel != null){
            socketChannel.writeAndFlush(msg);
        }
    }

    //    @PostConstruct
    public void start() {
        log.info("{}开始启动 tcp transmission client......", GlobalConstants.TCP_TRANSMISSION_LOG_ID);
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group)
                .channel(NioSocketChannel.class)
                .remoteAddress(host, port)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .option(ChannelOption.TCP_NODELAY, true)
                .handler(new TransmissionChannelInitializer());
        ChannelFuture future = bootstrap.connect();
        //客户端断线重连逻辑
        future.addListener((ChannelFutureListener) future1 -> {
            if (future1.isSuccess()) {
                log.info("{}启动 tcp transmission client 成功，远程连接服务端{}:{}.....", GlobalConstants.TCP_TRANSMISSION_LOG_ID, host, port);
            } else {
                int sec = 20;
                log.info("{}启动 tcp transmission client 失败，{} 秒后进行重连......", GlobalConstants.TCP_TRANSMISSION_LOG_ID, sec);
                future1.channel().eventLoop().schedule(() -> start(), 20, TimeUnit.SECONDS);
            }
        });
        socketChannel = (SocketChannel) future.channel();
    }
}
